﻿using Frame.Core.Models;
using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Threading.Tasks;

namespace Frame.Core.IServices
{
    public interface IBaseService<TEntity> where TEntity : class
    {
        /// <summary>
        /// 左连接查询
        /// </summary>
        /// <param name="leftJoinExpression"></param>
        /// <param name="exp"></param>
        /// <returns></returns>
        Task<TEntity> GetLeftJoinAsync(Expression<Func<TEntity, bool>> leftJoinExpression, Expression<Func<TEntity, bool>> exp);

        /// <summary>
        /// 根据条件获取实体
        /// </summary>
        /// <param name="exp"></param>
        /// <returns></returns>
        Task<TEntity> GetAsync(Expression<Func<TEntity, bool>> exp);

        /// <summary>
        /// 根据条件获取Dto
        /// </summary>
        /// <param name="exp"></param>
        /// <returns></returns>
        Task<TDto> GetAsync<TDto>(Expression<Func<TEntity, bool>> exp);

        /// <summary>
        /// 根据条件获取集合
        /// </summary>
        /// <param name="exp"></param>
        /// <returns></returns>
        Task<List<TEntity>> GetListAsync(Expression<Func<TEntity, bool>> exp);

        /// <summary>
        /// 插入数据，若实体有自增列，插入后的自增值会填充到实体中
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        Task<TEntity> AddAsync(TEntity entity);

        /// <summary>
        /// 批量插入
        /// </summary>
        /// <param name="entitys"></param>
        /// <returns></returns>
        Task<IEnumerable<TEntity>> AddAsync(IEnumerable<TEntity> entitys);

        /// <summary>
        /// 更新数据
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        Task<int> EditAsync(TEntity entity);

        /// <summary>
        /// 只更新变化的属性
        /// </summary>
        /// <param name="oldobj"></param>
        /// <param name="newObj"></param>
        /// <returns></returns>
        Task<int> AttachEditAsync(TEntity oldobj, TEntity newObj);

        /// <summary>
        /// 更新指定列
        /// </summary>
        /// <param name="setExpression"></param>
        /// <param name="exp"></param>
        /// <returns></returns>
        Task<int> EditSingeColumnAsync(Expression<Func<TEntity, object>> setExpression, Expression<Func<TEntity, bool>> exp);

        /// <summary>
        /// 删除数据
        /// </summary>
        /// <param name="exp"></param>
        /// <returns></returns>
        Task<int> DelAsync(Expression<Func<TEntity, bool>> exp);

        /// <summary>
        /// 排序和分页
        /// </summary>
        /// <param name="whereExpression">条件</param>
        /// <param name="pageInfo">分页属性</param>
        /// <param name="includeExpression">贪婪加载导航属性，如果查询中已经使用了 a.Parent.Parent 类似表达式，则可以无需此操作</param>
        /// <returns></returns>
        Task<PagingInfoViewModel<TEntity>> QueryAsync(Expression<Func<TEntity, bool>> whereExpression, PagingInfoViewModel<TEntity> pageInfo, Expression<Func<TEntity, TEntity>> includeExpression = null);

    }
}
